import * as fs from 'fs';

export interface SpringBootOptimizationResult {
  success: boolean;
  message: string;
  optimizationsApplied: string[];
  filesModified: string[];
  configFilesRemoved: string[];
  errors?: string[];
}

export class SpringBootAnnotationOptimizer {
  
  /**
   * 优化SpringBoot注入模式为注解方式
   */
  async optimizeToAnnotationBased(filePath: string): Promise<SpringBootOptimizationResult> {
    const result: SpringBootOptimizationResult = {
      success: false,
      message: '',
      optimizationsApplied: [],
      filesModified: [],
      configFilesRemoved: [],
      errors: []
    };

    try {
      const content = fs.readFileSync(filePath, 'utf-8');
      let optimizedContent = content;
      let hasChanges = false;

      // 1. 移除@Autowired注解，使用构造函数注入
      const constructorResult = this.optimizeToConstructorInjection(optimizedContent);
      if (constructorResult.modified) {
        optimizedContent = constructorResult.content;
        hasChanges = true;
        result.optimizationsApplied.push(...constructorResult.changes);
      }

      // 2. 优化@Component注解
      const componentResult = this.optimizeComponentAnnotations(optimizedContent);
      if (componentResult.modified) {
        optimizedContent = componentResult.content;
        hasChanges = true;
        result.optimizationsApplied.push(...componentResult.changes);
      }

      // 3. 优化配置类
      const configResult = this.optimizeConfigurationClasses(optimizedContent);
      if (configResult.modified) {
        optimizedContent = configResult.content;
        hasChanges = true;
        result.optimizationsApplied.push(...configResult.changes);
      }

      // 4. 添加必要的import
      optimizedContent = this.addRequiredImports(optimizedContent, result.optimizationsApplied);

      if (hasChanges) {
        fs.writeFileSync(filePath, optimizedContent);
        result.filesModified.push(filePath);
        result.success = true;
        result.message = `应用了 ${result.optimizationsApplied.length} 个SpringBoot注解优化`;
      } else {
        result.success = true;
        result.message = '代码已经很好地使用了SpringBoot注解，无需优化';
      }

    } catch (error) {
      result.errors?.push(`SpringBoot优化失败: ${error}`);
      result.message = `SpringBoot优化失败: ${error}`;
    }

    return result;
  }

  private optimizeToConstructorInjection(content: string): {
    content: string,
    modified: boolean,
    changes: string[]
  } {
    const changes: string[] = [];
    let modifiedContent = content;
    let modified = false;

    // 查找@Autowired字段
    const autowiredFieldPattern = /@Autowired\s+(?:private\s+)?([A-Z]\w+)\s+(\w+)\s*;/g;
    const autowiredFields: Array<{type: string, name: string, fullMatch: string}> = [];
    
    let match;
    while ((match = autowiredFieldPattern.exec(content)) !== null) {
      autowiredFields.push({
        type: match[1],
        name: match[2],
        fullMatch: match[0]
      });
    }

    if (autowiredFields.length > 0) {
      // 🚨 DEBUG: 确认这是我们的新代码正在运行
      console.error('🔥 CLAUDE_DEBUG: 新版@AllArgsConstructor代码正在执行！字段数量:', autowiredFields.length);
      
      // 1. 移除@Autowired注解，改为private final
      for (const field of autowiredFields) {
        const newFieldDeclaration = `    private final ${field.type} ${field.name};`;
        modifiedContent = modifiedContent.replace(field.fullMatch, newFieldDeclaration);
        changes.push(`🔧 将@Autowired字段 ${field.name} 改为final字段 [新代码正在运行]`);
        modified = true;
      }

      // 2. 添加@AllArgsConstructor注解到类声明 (而不是手动构造函数)
      const classAnnotationResult = this.addAllArgsConstructorAnnotation(modifiedContent);
      if (classAnnotationResult.modified) {
        modifiedContent = classAnnotationResult.content;
        changes.push('🎯 添加@AllArgsConstructor注解实现构造器注入 [NEW_CODE_VERSION]');
        modified = true;
      }
    }

    return { content: modifiedContent, modified, changes };
  }

  private optimizeComponentAnnotations(content: string): {
    content: string,
    modified: boolean,
    changes: string[]
  } {
    const changes: string[] = [];
    let modifiedContent = content;
    let modified = false;

    // 优化@Component为更具体的注解
    const optimizations = [
      {
        pattern: /@Component\s+public\s+class\s+(\w*Service)/g,
        replacement: '@Service\npublic class $1',
        description: 'Service类'
      },
      {
        pattern: /@Component\s+public\s+class\s+(\w*Repository)/g,
        replacement: '@Repository\npublic class $1',
        description: 'Repository类'
      },
      {
        pattern: /@Component\s+public\s+class\s+(\w*Controller)/g,
        replacement: '@RestController\npublic class $1',
        description: 'Controller类'
      },
      {
        pattern: /@Component\s+public\s+class\s+(\w*Config)/g,
        replacement: '@Configuration\npublic class $1',
        description: 'Configuration类'
      }
    ];

    for (const opt of optimizations) {
      if (opt.pattern.test(modifiedContent)) {
        modifiedContent = modifiedContent.replace(opt.pattern, opt.replacement);
        changes.push(`优化@Component为更具体的${opt.description}注解`);
        modified = true;
      }
    }

    return { content: modifiedContent, modified, changes };
  }

  private optimizeConfigurationClasses(content: string): {
    content: string,
    modified: boolean,
    changes: string[]
  } {
    const changes: string[] = [];
    let modifiedContent = content;
    let modified = false;

    // 为@Bean方法添加最佳实践注解
    const beanMethodPattern = /@Bean\s+public\s+(\w+)\s+(\w+)\(/g;
    let match;

    while ((match = beanMethodPattern.exec(content)) !== null) {
      const returnType = match[1];
      const methodName = match[2];
      
      // 如果返回类型是常见的需要单例的类型，添加@Scope
      if (this.shouldBeSingleton(returnType)) {
        const replacement = `@Bean\n    @Scope("singleton")\n    public ${returnType} ${methodName}(`;
        modifiedContent = modifiedContent.replace(match[0], replacement);
        changes.push(`为Bean方法 ${methodName} 添加了@Scope注解`);
        modified = true;
      }
    }

    // 为配置类添加@EnableAutoConfiguration
    if (/@Configuration/.test(modifiedContent) && !/@EnableAutoConfiguration/.test(modifiedContent)) {
      modifiedContent = modifiedContent.replace(
        /@Configuration/,
        '@Configuration\n@EnableAutoConfiguration'
      );
      changes.push('为配置类添加了@EnableAutoConfiguration注解');
      modified = true;
    }

    return { content: modifiedContent, modified, changes };
  }

  private addAllArgsConstructorAnnotation(content: string): {
    content: string,
    modified: boolean
  } {
    // 检查是否已有@AllArgsConstructor
    if (content.includes('@AllArgsConstructor')) {
      return { content, modified: false };
    }

    // 找到类声明，在其前添加@AllArgsConstructor注解
    const classPattern = /(@\w+[\s\n]*)*public\s+class\s+\w+/;
    const match = classPattern.exec(content);
    
    if (match) {
      const classDeclarationStart = match.index!;
      const modifiedContent = 
        content.slice(0, classDeclarationStart) +
        '@AllArgsConstructor\n' +
        content.slice(classDeclarationStart);
        
      return { content: modifiedContent, modified: true };
    }
    
    return { content, modified: false };
  }

  private extractClassName(content: string): string {
    const classMatch = content.match(/public\s+class\s+(\w+)/);
    return classMatch ? classMatch[1] : 'UnknownClass';
  }

  private shouldBeSingleton(returnType: string): boolean {
    const singletonTypes = [
      'DataSource', 'EntityManager', 'RestTemplate', 'WebClient',
      'RedisTemplate', 'JdbcTemplate', 'MessageProducer'
    ];
    return singletonTypes.includes(returnType);
  }

  private addRequiredImports(content: string, optimizations: string[]): string {
    let modifiedContent = content;
    const requiredImports = new Set<string>();

    // 根据应用的优化确定需要的import
    for (const optimization of optimizations) {
      if (optimization.includes('@AllArgsConstructor')) {
        requiredImports.add('import lombok.AllArgsConstructor;');
      }
      if (optimization.includes('构造函数注入')) {
        // 构造函数注入不需要额外import
      }
      if (optimization.includes('@Service')) {
        requiredImports.add('import org.springframework.stereotype.Service;');
      }
      if (optimization.includes('@Repository')) {
        requiredImports.add('import org.springframework.stereotype.Repository;');
      }
      if (optimization.includes('@RestController')) {
        requiredImports.add('import org.springframework.web.bind.annotation.RestController;');
      }
      if (optimization.includes('@Configuration')) {
        requiredImports.add('import org.springframework.context.annotation.Configuration;');
      }
      if (optimization.includes('@Scope')) {
        requiredImports.add('import org.springframework.context.annotation.Scope;');
      }
      if (optimization.includes('@EnableAutoConfiguration')) {
        requiredImports.add('import org.springframework.boot.autoconfiguration.EnableAutoConfiguration;');
      }
    }

    // 找到package声明后插入import
    const packageMatch = modifiedContent.match(/(package\s+[^;]+;)/);
    if (packageMatch && requiredImports.size > 0) {
      const importStatements = Array.from(requiredImports).join('\n');
      modifiedContent = modifiedContent.replace(
        packageMatch[1],
        packageMatch[1] + '\n\n' + importStatements
      );
    }

    return modifiedContent;
  }

  /**
   * 分析项目中的XML配置文件并建议迁移到注解
   */
  async analyzeXmlConfiguration(projectPath: string): Promise<{
    xmlFiles: string[],
    migrationSuggestions: string[]
  }> {
    const xmlFiles: string[] = [];
    const migrationSuggestions: string[] = [];

    try {
      const fs = require('fs');
      const path = require('path');

      // 查找XML配置文件
      const findXmlFiles = (dir: string) => {
        const items = fs.readdirSync(dir);
        for (const item of items) {
          const fullPath = path.join(dir, item);
          const stat = fs.statSync(fullPath);
          
          if (stat.isDirectory() && !item.startsWith('.')) {
            findXmlFiles(fullPath);
          } else if (item.endsWith('.xml') && 
                     (item.includes('applicationContext') || 
                      item.includes('spring') || 
                      item === 'beans.xml')) {
            xmlFiles.push(fullPath);
          }
        }
      };

      findXmlFiles(projectPath);

      // 分析XML配置并生成迁移建议
      for (const xmlFile of xmlFiles) {
        const xmlContent = fs.readFileSync(xmlFile, 'utf-8');
        
        if (xmlContent.includes('<bean')) {
          migrationSuggestions.push(`${xmlFile}: 包含<bean>定义，建议迁移到@Bean注解`);
        }
        if (xmlContent.includes('<component-scan')) {
          migrationSuggestions.push(`${xmlFile}: 包含组件扫描配置，建议迁移到@ComponentScan注解`);
        }
        if (xmlContent.includes('<tx:annotation-driven')) {
          migrationSuggestions.push(`${xmlFile}: 包含事务配置，建议迁移到@EnableTransactionManagement注解`);
        }
      }

    } catch (error) {
      migrationSuggestions.push(`分析XML配置时出错: ${error}`);
    }

    return { xmlFiles, migrationSuggestions };
  }
}